﻿using Max.PH5_2103A.Shopping.Frame.IRepository;
using Max.PH5_2103A.Shopping.Frame.IService;

namespace Max.PH5_2103A.Shopping.Frame.Service
{
    /// <summary>
    /// 基本的CRUD服务实现
    /// </summary>
    public class BaseService<T> : IBaseService<T> where T : class, new()
    {
        IBaseRepository<T> _repository;
        IUnitOfWork _unitOfWork;

        public BaseService(IBaseRepository<T> repository, IUnitOfWork unitOfWork)
        {
            _repository = repository;
            _unitOfWork = unitOfWork;
        }

        #region Delete 
        //删除一条数据
        public int Delete(T t)
        {
            _repository.Delete(t);
            int result = _unitOfWork.SaveChanges();
            return result;
        }

        //批量删除数据
        public int Delete(List<T> list)
        {
            int result = 0;
            using (var tran = _unitOfWork.GetContext().Database.BeginTransaction())  //开启事务
            {
                try
                {
                    _repository.Delete(list);
                    result = _unitOfWork.SaveChanges();
                    
                    tran.Commit(); //提交事务
                }
                catch (Exception)
                {
                    tran.Rollback(); //回滚事务
                    throw;
                }
            }
            return result;
        }
        #endregion

        #region Select

        //查询所有数据
        public IQueryable<T> GetAll()
        {
            return _repository.GetAll();
        }

        //查询分页
        public IQueryable<T> GetAll(int pageIndex, int pageSize, out int total)
        {
            var data = _repository.GetAll();
            total = data.Count();
            data = data.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return data;
        }

        //带条件查询分页
        public IQueryable<T> GetAll(Func<T, bool> where, int pageIndex, int pageSize, out int total)
        {
            var data = _repository.GetAll().Where(where);
            total = data.Count();
            data = data.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return data.AsQueryable();
        }

        //带条件查询及排序的分页数据
        public IQueryable<T> GetAll<TKey>(Func<T, bool> where, Func<T, TKey> sort, bool isAsc, int pageIndex, int pageSize, out int total)
        {
            var data = _repository.GetAll().Where(where);
            total = data.Count();

            //排序是在查询后，对结果进行排序
            if (isAsc)
            {
                data = data.OrderBy(sort);
            }
            else
            {
                data = data.OrderByDescending(sort);
            }

            data = data.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return data.AsQueryable();
        }

        //查询一条数据
        public T GetFirstById(object id)
        {
            return _repository.GetFirstById(id);
        }
        #endregion

        #region Insert

        //添加一条数据
        public int Insert(T t)
        {
            _repository.Insert(t);
            int result = _unitOfWork.SaveChanges();
            return result;
        }

        //批量添加数据
        public int Insert(List<T> list)
        {
            int result = 0;
            using (var tran = _unitOfWork.GetContext().Database.BeginTransaction())  //开启事务
            {
                try
                {
                    _repository.Insert(list);
                    result = _unitOfWork.SaveChanges();

                    tran.Commit(); //提交事务
                }
                catch (Exception)
                {
                    tran.Rollback(); //回滚事务
                    throw;
                }
            }
            return result;
        }
        #endregion

        #region Update

        //修改一条数据
        public int Update(T t)
        {
            _repository.Update(t);
            int result = _unitOfWork.SaveChanges();
            return result;
        }

        //批量修改
        public int Update(List<T> list)
        {
            int result = 0;
            using (var tran = _unitOfWork.GetContext().Database.BeginTransaction())  //开启事务
            {
                try
                {
                    _repository.Update(list);
                    result = _unitOfWork.SaveChanges();

                    tran.Commit(); //提交事务
                }
                catch (Exception)
                {
                    tran.Rollback(); //回滚事务
                    throw;
                }
            }
            return result;
        }
        #endregion
    }
}